﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TVGuide.DataAccess.Common;
using TVGuide.DataAccess.Exceptions;

namespace TVGuide.DataAccess.Repository
{
    public class NotCatProgramRepository : INotCatProgramRepository
    {
        #region Singleton pattern

        private static tvchanneldbEntities model;
        private static NotCatProgramRepository instance;

        private NotCatProgramRepository() { model = new tvchanneldbEntities(); }

        public static NotCatProgramRepository Instance()
        {
            if (instance == null)
                instance = new NotCatProgramRepository();
            return instance;
        }

        #endregion

        #region IRepository<Program> Members

        public void Add(NotCatProgram item, bool commitChange)
        {
            if (item == null)
                throw new InvalidArgsException("The parameter is null");

            if (model.channels.FirstOrDefault(o => o.channelID == item.ChannelId) == null)
                throw new InvalidArgsException("Invalid channelId");           

            DateTime dt = new DateTime(2000, 01, 01);

            if (item.Date < dt)
                throw new InvalidArgsException("The 'date'property is null");

            if (String.IsNullOrEmpty(item.Name))
                throw new InvalidArgsException("The 'title' property is null or empty");

            if (item.CountryId != null)
            {
                try
                {
                    if (model.countries.FirstOrDefault(o => o.countryID == item.CountryId) == null)
                        throw new InvalidArgsException("Invalid countryId");
                }
                catch (InvalidOperationException)
                {
                    throw new InvalidArgsException("Invalid countryId");
                }
            }

            if (item.CategoryId != null)
            {
                if (model.categories.FirstOrDefault(o => o.catID == item.CategoryId) == null)
                    throw new InvalidArgsException("Invalid categoryId");
            }

            model.notCatPrograms.AddObject((notCatProgram)item);

            if (commitChange)
                model.SaveChanges();
        }

        public void Add(NotCatProgram item)
        {
            Add(item, true);
        }

        public void AddRange(IEnumerable<NotCatProgram> items)
        {
            try
            {
                foreach (var item in items)
                {
                    Add(item, false);
                }
            }
            catch (InvalidArgsException e)
            {
                // TODO rollback changes.
                InvalidArgsException ex = new InvalidArgsException(e.Message + "\nNo items were committed.");
                throw ex;
            }
            model.SaveChanges();
        }

        public NotCatProgram Get(int id)
        {
            return null;
        }

        public IEnumerable<NotCatProgram> Get(Predicate<NotCatProgram> func)
        {
            List<NotCatProgram> progList = new List<NotCatProgram>();
            foreach (var item in model.notCatPrograms)
            {
                NotCatProgram dataObj = (NotCatProgram)item;
                if(func(dataObj))
                    progList.Add(dataObj);
            }
            return progList;
        }

        public IEnumerable<NotCatProgram> GetAllItems()
        {
            List<NotCatProgram> listProg = new List<NotCatProgram>();
            foreach (var item in model.notCatPrograms)
            {
                listProg.Add((NotCatProgram)item);
            }
            return listProg;
        }

        public void Remove(int id) { }

        public void Remove(Predicate<NotCatProgram> func)
        {
            List<notCatProgram> removeList = new List<notCatProgram>();
            foreach (var item in model.notCatPrograms)
            {
                if (func((NotCatProgram)item))
                    removeList.Add(item);

                foreach (var item1 in removeList)
                {
                    model.notCatPrograms.DeleteObject(item1);
                }
            }
            model.SaveChanges();
        }

        public void RemoveAll()
        {
            Remove(o => true);
        }

        #endregion
    }
}
